#pragma once

#include <iostream>
#include <string>
#include <cstdio>
#include <set>
#include "InetAddr.hpp"
#include "Log.hpp"

using namespace LogMoudle;

class Command
{
public:
    Command()
    {
        // 严格匹配
        _WhiteCommands.insert("ls");
        _WhiteCommands.insert("pwd");
        _WhiteCommands.insert("ls -l");
        _WhiteCommands.insert("touch haha.txt");
        _WhiteCommands.insert("whoami");

    }

    bool IsSafeCommand(std::string cmd)
    {
        auto iter = _WhiteCommands.find(cmd);
        return iter != _WhiteCommands.end();
    }

    std::string Execute(const std::string& cmd, InetAddr &addr)
    {
        // 1. 属于白名单命令
        if(!IsSafeCommand(cmd))
        {
            return std::string("坏人");
        }

        std::string who = addr.StringAddr(); // 客户端

        // 2. 执行命令
        // popen执行后会创建管道和子进程，子进程的标准输出/标准输入，重定向到管道的“r”端/“w”端
        FILE *fp = popen(cmd.c_str(), "r");
        if(fp == nullptr)
        {
            return std::string("你要执行的命令不存在： ") + cmd;
        }

        std::string res;
        char line[1024];
        while (fgets(line, sizeof(line), fp)) // 文件读取到缓冲区
        {
            res += line;
        }
        pclose(fp);
        std::string result =  "ececute done, result is : \n" + res;
        LOG(LogLevel::DEBUG) << result; 
        return result;
    }

    ~Command()
    {}
private:
    // 受限制的远程执行, 设置白名单
    std::set<std::string> _WhiteCommands;

};